package com.yisu.expressway.customService;

import android.content.Context;
import android.content.Intent;
import android.databinding.DataBindingUtil;
import android.os.Environment;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;

import com.google.gson.Gson;
import com.iflytek.cloud.ErrorCode;
import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechUnderstander;
import com.iflytek.cloud.SpeechUnderstanderListener;
import com.iflytek.cloud.UnderstanderResult;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.ObjectAnimator;
import com.nineoldandroids.animation.ValueAnimator;
import com.yisu.expressway.R;
import com.yisu.expressway.activity.BaseActivity;
import com.yisu.expressway.customService.adapter.VoiceAssistantAdapter;
import com.yisu.expressway.customService.model.AnswerObj;
import com.yisu.expressway.customService.model.ChatContentObj;
import com.yisu.expressway.customService.model.HighWayInfoObj;
import com.yisu.expressway.customService.model.ServiceModuleID;
import com.yisu.expressway.customService.utils.GetAnswerUtils;
import com.yisu.expressway.databinding.ActivityVoiceAssistantBinding;
import com.yisu.expressway.location.LocationInfo;
import com.yisu.expressway.location.LocationListener;
import com.yisu.expressway.location.LocationService;
import com.yisu.expressway.service_district.MapActivity;
import com.yisu.expressway.ui.recyclerview.DividerListItemDecoration;
import com.yisu.expressway.utils.AnimationUtils;
import com.yisu.expressway.utils.StringUtil;
import com.yisu.expressway.utils.ToastUtil;


public class VoiceAssistantActivity extends BaseActivity implements SpeechUnderstanderListener {

    ActivityVoiceAssistantBinding binding;
    private SpeechUnderstander mSpeechUnderstander;
    private final static String QUESTION_VOICE_PATH = Environment.getExternalStorageDirectory()+"/msc/sud.wav";

    private final String START_TIME_OUT_INTERVAL = "4000";
    private final String END_SPEAK_TIME_OUT = "1000";
    private final int USER_NO_SPEAK_ERROR = 10118;


    private final static String SELECT_MODULE_ID = "select_module_id";

    private int ret = 0;

    private Gson gson;
    private VoiceAssistantAdapter mAdapter;
    private LinearLayoutManager mLinearLayoutManager;
    private boolean move;
    private int mIndex = 0;
    private RecyclerView mRecyclerView;
    private ServiceModuleID serviceModuleID;
    private LocationInfo locInfo;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this,R.layout.activity_voice_assistant);
        init(getIntent());
    }

    private void init(Intent intent){
        setTitle(R.string.my_custome_service);
        mAdapter = new VoiceAssistantAdapter(this);
        mRecyclerView = binding.rvList;
        mLinearLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLinearLayoutManager);
        mRecyclerView.addItemDecoration(new DividerListItemDecoration(this,LinearLayoutManager.VERTICAL,8,R.color.transparent));
        mRecyclerView.setAdapter(mAdapter);
        mRecyclerView.addOnScrollListener(new RecyclerViewListener());
        TTSPlayer.getmInstance().init(this);
        VoiceRecognizer.getInstance().init(this);
        initVoiceParams();
        getCurrentLocation();
        if(intent != null){
            serviceModuleID = (ServiceModuleID)intent.getSerializableExtra(SELECT_MODULE_ID);
            if(serviceModuleID != null){
                initCustomAnswer();
            }
        }

    }

    public static void launch(Context context){
        Intent intent = new Intent(context, VoiceAssistantActivity.class);
        context.startActivity(intent);
    }

    public static void launch(Context context, ServiceModuleID moduleID){
        Intent intent = new Intent(context, VoiceAssistantActivity.class);
        intent.putExtra(SELECT_MODULE_ID,moduleID);
        context.startActivity(intent);
    }

    private void initCustomAnswer(){
        switch (serviceModuleID){
            case WEATHER_CONDITION:
                addCustomeAnswer(R.string.weather_guide_notify);
                break;
            case SERVICE_DISTRICT_AREA:
                locInfo = LocationService.getInstance().getLocationResult();
                if(locInfo != null){
                    showLoading();
                    GetAnswerUtils.getNearByDistrictList(locInfo, new GetAnswerUtils.answerResultListener() {
                        @Override
                        public void onGetAnswer(ChatContentObj answerObj) {
                            dismissLoading();
                            if(answerObj == null){
                                addUnknownAnswer();
                            }else {
                                mAdapter.updateData(answerObj);
                            }
                        }
                    });
                }else {
                    LocationService.getInstance().start(new LocationListener() {
                        @Override
                        public void onSuccess(LocationInfo info) {
                            locInfo = info;
                            showLoading();
                            GetAnswerUtils.getNearByDistrictList(locInfo, new GetAnswerUtils.answerResultListener() {
                                @Override
                                public void onGetAnswer(ChatContentObj answerObj) {
                                    dismissLoading();
                                    updateView(answerObj);
                                }
                            });
                        }

                        @Override
                        public void onFailure(int errorCode, String errorMessage) {
                        }
                    });
                }
                break;
            case HIGWAY_RESCUE:
                getHighWayAnswerFromServer(GetAnswerUtils.HIGHWAY_INFO_LEVEL_RESCUE,getString(R.string.highway_rescue_module));
                break;
            case FEE_STANDARD:
                getHighWayAnswerFromServer(GetAnswerUtils.HIGHWAY_INFO_LEVEL_FEE_STANDARD,getString(R.string.highway_fee_standard));
                break;
            case HIGHWAY_FEE_RULE:
                getHighWayAnswerFromServer(GetAnswerUtils.HIGHWAY_INFO_LEVEL_FEE_RULES,getString(R.string.highway_fee_rule));
                break;
            case HIGHWAY_ILLEAGAL:
                getHighWayAnswerFromServer(GetAnswerUtils.HIGHWAY_INFO_LEVEL_ILLEGAL,getString(R.string.highway_illegal_moedule));
                break;
            case NAVIGATION_QUERY:
                addCustomeAnswer(R.string.highway_navi_route_notify);
                break;
            case HIGHWAY_CONDITION:
                addCustomeAnswer(R.string.highway_nearby_traffic_condition_suggestion);
                break;
            case IFLY_MODULE:
            default:
                addCustomeAnswer(R.string.welcome_content);
                break;
        }
    }

    public void click2Speak(View view){
        if(mSpeechUnderstander.isUnderstanding()){// 开始前检查状态
            mSpeechUnderstander.stopUnderstanding();

        }else {
            ret = mSpeechUnderstander.startUnderstanding(this);
            if(ret != 0){
                ToastUtil.displayShortToastMsg(this,"语义理解失败,错误码:"	+ ret);
            }else {
                showVoiceLine(true);
            }
        }
    }

    private void showVoiceLine(boolean isShow){
        AnimationUtils.startVoiceLineAnimation(isShow,binding.voiceLine,binding.ivAssistant);
    }

    private void initVoiceParams(){
        mSpeechUnderstander = SpeechUnderstander.createUnderstander(this, mSpeechUdrInitListener);
        mSpeechUnderstander.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
        // 设置语言区域
        mSpeechUnderstander.setParameter(SpeechConstant.ACCENT, "mandarin");
        // 设置语音前端点:静音超时时间，即用户多长时间不说话则当做超时处理
        mSpeechUnderstander.setParameter(SpeechConstant.VAD_BOS, START_TIME_OUT_INTERVAL);
        // 设置语音后端点:后端点静音检测时间，即用户停止说话多长时间内即认为不再输入， 自动停止录音
        mSpeechUnderstander.setParameter(SpeechConstant.VAD_EOS, END_SPEAK_TIME_OUT);

        // 设置标点符号，默认：1（有标点）
        mSpeechUnderstander.setParameter(SpeechConstant.ASR_PTT, "0");

        // 设置音频保存路径，保存音频格式支持pcm、wav，设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
        mSpeechUnderstander.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
        mSpeechUnderstander.setParameter(SpeechConstant.ASR_AUDIO_PATH, QUESTION_VOICE_PATH);
    }

    /**
     * 初始化监听器（语音到语义）。
     */
    private InitListener mSpeechUdrInitListener = new InitListener() {

        @Override
        public void onInit(int code) {
            if (code != ErrorCode.SUCCESS) {

            }
        }
    };


    @Override
    public void onVolumeChanged(int volume, byte[] bytes) {
        binding.voiceLine.setVolume(volume);
    }

    @Override
    public void onBeginOfSpeech() {
    }

    @Override
    public void onEndOfSpeech() {
        showVoiceLine(false);
    }

    @Override
    public void onResult(UnderstanderResult result) {

        if (null != result) {
            String text = result.getResultString();
            if (!StringUtil.isNullOrEmpty(text)) {
                updateResult(text);
            }
        } else {
            ToastUtil.displayShortToastMsg(VoiceAssistantActivity.this,R.string.no_answer_error);
        }

    }

    @Override
    public void onError(SpeechError speechError) {
       if(speechError.getErrorCode() == USER_NO_SPEAK_ERROR){
           addCustomeAnswer(R.string.no_speak);
       }
    }

    @Override
    public void onEvent(int i, int i1, int i2, Bundle bundle) {

    }

    private void addCustomeAnswer(int strRes){
        ChatContentObj welcome = new ChatContentObj();
        welcome.setText(getString(strRes));
        mAdapter.updateData(welcome);
    }

    private void addUnknownAnswer(){
        ChatContentObj unknownObj = new ChatContentObj();
        unknownObj.setText(getString(R.string.default_answer_read_text));
        unknownObj.setQuestionType(VoiceAssistantAdapter.ITEM_TYPE_UNKNOWN_ANSWER);
        mAdapter.updateData(unknownObj);
    }

    private void updateResult(String resultJson){
        if(gson == null) {
            gson = new Gson();
        }

        final AnswerObj answerObj = gson.fromJson(resultJson,AnswerObj.class);
        if(answerObj != null){
            ChatContentObj chatContentObj = answerObj.answer;
            ChatContentObj questionObj = new ChatContentObj();
            questionObj.setText(answerObj.text);
            questionObj.setQuestionType(VoiceAssistantAdapter.ITEM_TYPE_QUESTION);
            questionObj.setQuestion(true);
            mAdapter.updateData(questionObj);

            switch (serviceModuleID){
                case WEATHER_CONDITION:
                    GetAnswerUtils.getWeather(answerObj.text, new GetAnswerUtils.answerResultListener() {
                        @Override
                        public void onGetAnswer(ChatContentObj answerObj) {
                            updateView(answerObj);
                        }
                    });
                    break;
                case NAVIGATION_QUERY:
                    GetAnswerUtils.getWayRoute(answerObj.text, new GetAnswerUtils.NaviRouteResultListener() {
                        @Override
                        public void onGetRouteResult(String start, String end) {
                            if(StringUtil.isNullOrEmpty(start)){
                                addUnknownAnswer();
                            }else {
                                double lontitude = -1;
                                double latitude = -1;
                                if(locInfo != null){
                                    lontitude = locInfo.getLongitude();
                                    latitude = locInfo.getLatitude();
                                }
                                MapActivity.launchRoutePlan(VoiceAssistantActivity.this,lontitude,latitude,start,end);
                            }
                        }
                    });
                    break;
                case SERVICE_DISTRICT_AREA:
                    GetAnswerUtils.getSearchDistrict(locInfo, answerObj.text, new GetAnswerUtils.answerResultListener() {
                        @Override
                        public void onGetAnswer(ChatContentObj answerObj) {
                            updateView(answerObj);
                        }
                    });
                    break;
                case HIGHWAY_CONDITION:
                    locInfo = LocationService.getInstance().getLocationResult();
                    if(locInfo != null) {
                        showLoading();
                        GetAnswerUtils.getNeayByWayInfo(locInfo, answerObj.text, new GetAnswerUtils.LocationResultListener() {
                            @Override
                            public void onGetLocationResult(double longitude, double latitude) {
                                dismissLoading();
                                if (longitude == -1) {
                                    addUnknownAnswer();
                                } else {
                                    MapActivity.launchTraffic(VoiceAssistantActivity.this, longitude, latitude);
                                }
                            }
                        });
                    }else {
                        LocationService.getInstance().start(new LocationListener() {
                            @Override
                            public void onSuccess(LocationInfo info) {
                                showLoading();
                                locInfo = info;
                                GetAnswerUtils.getNeayByWayInfo(locInfo, answerObj.text, new GetAnswerUtils.LocationResultListener() {
                                    @Override
                                    public void onGetLocationResult(double longitude, double latitude) {
                                        dismissLoading();
                                        if (longitude == -1) {
                                            addUnknownAnswer();
                                        } else {
                                            MapActivity.launchTraffic(VoiceAssistantActivity.this, longitude, latitude);
                                        }
                                    }
                                });
                            }

                            @Override
                            public void onFailure(int errorCode, String errorMessage) {
                            }
                        });
                    }
                    break;
                default:
                    if(chatContentObj != null && !StringUtil.isNullOrEmpty(chatContentObj.getText())) {
                        mAdapter.updateData(chatContentObj);
                    }else {
                        addUnknownAnswer();
                    }
                    moveToPosition(mAdapter.getItemCount());
                    break;
            }

        }

    }

    private void updateView(ChatContentObj chatContentObj){
        if(chatContentObj == null){
            addUnknownAnswer();
        }else {
            mAdapter.updateData(chatContentObj);
        }
        moveToPosition(mAdapter.getItemCount());
    }

    private void moveToPosition(int n) {
        mRecyclerView.smoothScrollToPosition(n);
        move = true;
    }

    class RecyclerViewListener extends RecyclerView.OnScrollListener{
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
            if (move && newState == RecyclerView.SCROLL_STATE_IDLE){
                move = false;
                int bottom = mRecyclerView.getChildAt(mRecyclerView.getChildCount() - 1).getBottom();
                mRecyclerView.smoothScrollBy(0, bottom);

            }
        }

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
        }
    }

    public void getHighWayAnswerFromServer(int levelId,String title){
        showLoading();
        GetAnswerUtils.getHighWayInfo(levelId,title, new GetAnswerUtils.answerResultListener() {
            @Override
            public void onGetAnswer(ChatContentObj answerObj) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        dismissLoading();
                    }
                });
                updateView(answerObj);
            }
        });
    }

    public void getHighWayAnswerFromItem(HighWayInfoObj infoObj){
        ChatContentObj answer = new ChatContentObj();
        answer.setText(infoObj.answer);
        mAdapter.updateData(answer);
        moveToPosition(mAdapter.getItemCount());
    }

    private void getCurrentLocation(){
        LocationService.getInstance().start(new LocationListener() {
            @Override
            public void onSuccess(LocationInfo info) {
                locInfo = info;
            }

            @Override
            public void onFailure(int errorCode, String errorMessage) {
            }
        });
    }

    @Override
    protected void onDestroy(){
        super.onDestroy();
        TTSPlayer.getmInstance().destroy();
    }
}
